package com.yc.cloud.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yc.cloud.api.constants.RedisKeyConstants;
import com.yc.cloud.api.enums.HWDeviceStatus;
import com.yc.cloud.common.cache.service.RedisService;
import com.yc.cloud.entity.HwDevice;
import com.yc.cloud.mapper.HwDeviceMapper;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class DeviceOnlineScheduler {

    @Resource
    private HwDeviceMapper hwDeviceMapper;
    @Resource
    private RedisService<Object> redisService;

    @Value("${device.onlineStatus.checkBatchSize:500}")
    private int checkBatchSize;

    /**
     * 每分钟扫描一次，将没有心跳的设备置为离线
     */
    @Scheduled(cron = "0 */1 * * * ?")
    public void markOfflineIfNoHeartbeat() {
        List<HwDevice> onlineDevices = hwDeviceMapper.selectList(new QueryWrapper<HwDevice>().eq(HwDevice.Status, HWDeviceStatus.ONLINE.getCode()));
        if (onlineDevices == null || onlineDevices.isEmpty()) {
            return;
        }
        List<Long> toOfflineIds = new ArrayList<>();
        List<Long> toCameraOfflineIds = new ArrayList<>();
        for (HwDevice device : onlineDevices) {
            String key = RedisKeyConstants.HW_DEVICE_ONLINE.replace(RedisKeyConstants.DEVICE_SN, device.getDeviceSn());
            if (!Boolean.TRUE.equals(redisService.hasKey(key))) {
                toOfflineIds.add(device.getId());
                if (toOfflineIds.size() >= checkBatchSize) {
                    batchOffline(toOfflineIds);
                    toOfflineIds.clear();
                }
            }
            String cameraKey = RedisKeyConstants.HW_CAMERA_ONLINE.replace(RedisKeyConstants.DEVICE_SN, device.getDeviceSn());
            if (!Boolean.TRUE.equals(redisService.hasKey(cameraKey))) {
                toCameraOfflineIds.add(device.getId());
                if (toCameraOfflineIds.size() >= checkBatchSize) {
                    batchCameraOffline(toCameraOfflineIds);
                    toCameraOfflineIds.clear();
                }
            }
        }
        if (!toOfflineIds.isEmpty()) {
            batchOffline(toOfflineIds);
        }
        if (!toCameraOfflineIds.isEmpty()) {
            batchCameraOffline(toCameraOfflineIds);
        }
    }

    private void batchOffline(List<Long> deviceIds) {
        if (deviceIds == null || deviceIds.isEmpty()) {
            return;
        }
        HwDevice update = new HwDevice();
        update.setStatus(HWDeviceStatus.OFFLINE.getCode());
        hwDeviceMapper.update(update, new QueryWrapper<HwDevice>().in(HwDevice.ID, deviceIds));
    }

    private void batchCameraOffline(List<Long> deviceIds) {
        if (deviceIds == null || deviceIds.isEmpty()) {
            return;
        }
        HwDevice update = new HwDevice();
        // 摄像头在线状态：0-离线, 1-在线, 2-故障, TODO 后面要去修改HWCamera对象
//        update.setCameraOnlineStatus(0);
        hwDeviceMapper.update(update, new QueryWrapper<HwDevice>().in(HwDevice.ID, deviceIds));
    }
}


